package com.meida.module.bus.provider.api.util;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.groovy.provider.script.MyGroovyScriptEngine;
import com.meida.module.bus.client.entity.*;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmMaterial;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmProjectinfo;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmService;
import com.meida.module.bus.client.entity.srmapi.basedata.SrmUnit;
import com.meida.module.bus.provider.api.config.MaterialNoSyncCk;
import com.meida.module.bus.provider.service.*;
import com.meida.module.bus.provider.service.srmservice.SrmProjectinfoMysqlService;
import com.meida.module.bus.provider.service.srmservice.SrmUnitService;
import com.meida.module.system.client.entity.SysDict;
import com.meida.module.system.client.entity.SysDictData;
import com.meida.module.system.provider.service.SysDictDataService;
import com.meida.module.system.provider.service.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@Component
public class PmsApiUtil {
    @Autowired
    private SrmProjectinfoMysqlService projectinfoMysqlService;
    @Autowired
    private BusProjectService busProjectService;
    @Autowired
    private BusMaterialPlan100Service plan100Service;
    @Autowired
    private BusMaterialPlan200Service plan200Service;
    @Autowired
    private BusMaterialPackage100Service package100Service;
    @Autowired
    private BusMaterialPackage200Service package200Service;
    @Autowired
    private SrmUnitService srmUnitService;
    @Autowired
    private SysDictDataService dictDataService;
    @Autowired
    private SysDictService dictService;
    @Autowired
    private BusMaterialSrmService busMaterialSrmService;
    @Autowired
    private BusMaterialSrmSubService busMaterialSrmSubService;
    // PMS-材料关联SRM表数据-送货单
    @Autowired
    private BusDeliverSrmService busDeliverSrmService;
    @Autowired
    private BusPurchaseDetailsService busPurchaseDetailsService;
    @Autowired
    private BusMaterialService busMaterialService;
    @Autowired
    private BusVersionService busVersionService;
    @Autowired
    private BusProjectPackSyncSrmService packSyncSrmService;
    @Autowired
    private BusProjectSupplierService projectSupplierService;
    @Autowired
    private BusSupplierService supplierService;
    @Autowired
    private SrmMaterialService srmMaterialService;
    @Autowired
    private BusMaterialViewService busMaterialViewService;
    @Autowired
    private MaterialNoSyncCk materialNoSyncCk;
    @Autowired
    private BusMajorService busMajorService;
    @Autowired
    private SrmServiceService srmServiceService;
    @Autowired
    private BusReportService busReportService;
    @Autowired
    private BusProjectPackSyncSrmService busProjectPackSyncSrmService;

    public SrmProjectinfo getProjectInfoFromSrm(Long projectId) {
        BusProject busProject = busProjectService.getById(projectId);
        if (null != busProject) {
            SrmProjectinfo srmProjectinfo = projectinfoMysqlService.getByProperty("projectCode", busProject.getProjectCode());
            if (null != srmProjectinfo) {
                return srmProjectinfo;
            }
        }
        return new SrmProjectinfo();
    }

    public BusProject getProjectInfo(Long projectId) {
        return busProjectService.getById(projectId);
    }

    public static Boolean checkLong(Long val) {
        if (0L == val || null == val) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    public List<String> getAuthMajorCodes(Long userId) {
        List<String> majorCodes = busMajorService.getUserMajors(userId);
        if (majorCodes.size() > 0) {
            if (!majorCodes.contains("P99")) {
                return majorCodes;
            }
        }
        return null;
    }

    public List<String> getAuthProjectIds(Long userId) {
        List<String> projectCodes = busProjectService.getProjectCodes(userId);
        if (0 < projectCodes.size()) {
            return projectCodes;
        }
        return null;
    }

//    /**
//     * 检查材料申请行是否与左侧的物料行一致
//     *
//     * @param busMaterialObjIn
//     * @param ver
//     * @param detailObj
//     * @return
//     */
//    public static Boolean checkPurorderWithPlan(Object busMaterialObjIn, int ver, BusPurchaseDetails detailObj) {
//        if (ApiConstants.VER_100 == ver) {
//            BusMaterialPlan100 busMaterialPlan100 = (BusMaterialPlan100) busMaterialObjIn;
//            if (busMaterialPlan100.getProjectId().equals(detailObj.getProjectId())
//                && busMaterialPlan100.getMaterialId().equals(detailObj.getMaterialId())) {
//                return Boolean.TRUE;
//            }
//        } else {
//            // TODO:等待200
//            return Boolean.TRUE;
//        }
//        return Boolean.FALSE;
//    }

    public String getUnitCode(String unitName) {
        CriteriaQuery<SrmUnit> srmUnitCriteriaQuery = new CriteriaQuery(SrmUnit.class);
        srmUnitCriteriaQuery.in("unitName", unitName);
        List<SrmUnit> busMaterialList = srmUnitService.list(srmUnitCriteriaQuery);

//        SrmUnit srmUnit = srmUnitService.getByProperty("unitName", unitName);
        if (0 == busMaterialList.size()) {
            srmUnitCriteriaQuery = new CriteriaQuery(SrmUnit.class);
            srmUnitCriteriaQuery.in("unitCode", unitName);
            busMaterialList = srmUnitService.list(srmUnitCriteriaQuery);
            if (0 < busMaterialList.size()) {
                return busMaterialList.get(0).getUnitCode();
            } else {
                return null;
            }
        }
        return busMaterialList.get(0).getUnitCode();
    }

    public SrmUnit getSrmUnitByMaterialCode(String materialCode) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_MATERIALCODE, materialCode);
        Collection<SrmMaterial> srmMaterials = srmMaterialService.listByMap(searchMap);
        if (0 < srmMaterials.size()) {
            return srmUnitService.getByProperty("unitCode", srmMaterials.stream().findFirst().get().getBaseUnitCode());
        }
        return new SrmUnit();
    }

    /**
     * SRM关联表更新
     *
     * @param busMaterialSrms busMaterialSrms
     */
    public void saveOrUpDateBusMaterialSrm(List<BusMaterialSrm> busMaterialSrms) {
        busMaterialSrms.stream().forEach(busMaterialSrm -> {
            Map<String, Object> param = Maps.newHashMap();
            param.put(ApiConstants.MAP_PURCHASEID, busMaterialSrm.getPurchaseId());
            param.put(ApiConstants.MAP_PURCHASEDETAILSID, busMaterialSrm.getPurchaseDetailsId());
            Collection<BusMaterialSrm> busMaterialSrmsColl = busMaterialSrmService.listByMap(param);
            if (2 > busMaterialSrmsColl.size()) {
                if (busMaterialSrmsColl.size() == 1) {
                    busMaterialSrm.setBusMaterialSrmId(busMaterialSrmsColl.stream().findFirst().get().getBusMaterialSrmId());
                }
                busMaterialSrmService.saveOrUpdate(busMaterialSrm);
            }

        });
    }

    /**
     * SRM关联-送货单表更新
     *
     * @param busDeliverSrms busDeliverSrms
     */
    public void saveOrUpDateBusDeliverSrm(List<BusDeliverSrm> busDeliverSrms) {
        busDeliverSrms.stream().forEach(busDeliverSrm -> {
            Map<String, Object> param = Maps.newHashMap();
            param.put("purchaseId", busDeliverSrm.getPurchaseId());
            param.put("purchaseDetailsId", busDeliverSrm.getPurchaseDetailsId());
            Collection<BusDeliverSrm> busMaterialSrmsColl = busDeliverSrmService.listByMap(param);
            if (0 < busMaterialSrmsColl.size()) {
                busDeliverSrm.setBusDeliverSrmId(busMaterialSrmsColl.stream().findFirst().get().getBusDeliverSrmId());
            }
//            else {
//                busDeliverSrmService.save(busDeliverSrm);
//
//            }
            busDeliverSrmService.saveOrUpdate(busDeliverSrm);
        });
    }

    /**
     * 获取材料最新计划Object
     *
     * @param purchaseDetailsId 材料申请明细ID
     * @return
     */
    public Object getMaterialPlanDataObj(Long purchaseDetailsId, Long projectrId, BusPurchaseDetails busPurchaseDetails) {
        BusPurchaseDetails busPurchaseDetailsObj = projectrId == null ? busPurchaseDetailsService.getById(purchaseDetailsId) : busPurchaseDetails;
        Long projectIdSearch = projectrId == null ? busPurchaseDetailsObj.getProjectId() : projectrId;
        if (getLastVer(projectIdSearch, 0)) {
            return plan100Service.getById(busPurchaseDetailsObj.getMaterialId());
        }
        Object planDataObj = plan200Service.getById(busPurchaseDetailsObj.getMaterialId());
        // 材料申请是100下的单子，但是版本计划数据却升级到了200版
        if (null == planDataObj) {
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("packagePlan100Id", busPurchaseDetailsObj.getMaterialId());
            Collection<BusMaterialPlan200> planDataObjs = plan200Service.listByMap(paramMap);
            planDataObj = planDataObjs.stream().findFirst().get();
        }
        return planDataObj;
    }

    /**
     * 获取材料最新计划Object
     *
     * @return
     */
    public List<Object> getMaterialPackageDataObjList(Long projectId, String majorCode, String packageNo, Long parentId) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        if (null == parentId || 0L == parentId) {
            searchMap.put(ApiConstants.MAP_PARENTID, 0L);
        }
        List<Object> packLists = Lists.newArrayList();
        if (getLastVer(projectId, 1)) {
            package100Service.listByMap(searchMap).stream().forEach(pack100 -> {
                packLists.add(pack100);
            });
        } else {
            package200Service.listByMap(searchMap).stream().forEach(pack200 -> {
                packLists.add(pack200);
            });
        }
        StaticLog.debug("getMaterialPackageDataObjList---找到的原始需要同步的数据--" + JSONArray.toJSONString(packLists));
        StaticLog.debug("getMaterialPackageDataObjList---找到的原始需要同步的数据-----------------------------------");
        StaticLog.debug("getMaterialPackageDataObjList---找到的原始需要同步的数据--" + JSONArray.toJSONString(packLists));
        BusProjectSupplier busProjectSupplier = getBusProjectSupplier(projectId, majorCode, packageNo);
        List<Object> returnLists = Lists.newArrayList();
        packLists.stream().forEach(packObj -> {
            List<BigDecimal> supplierNums = Lists.newArrayList();
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                BigDecimal supplierNum = PmsToolUtil.getBigDecimalValue(packObj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);
                StaticLog.debug("getMaterialPackageDataObjList---supplierNum" + supplierNum + "i:" + i);
                if (null != supplierNum && BigDecimal.ZERO.compareTo(supplierNum) < 0) {
                    supplierNums.add(supplierNum);
                    //设置分包供应商ID
                    PmsToolUtil.setValue(packObj,
                        ApiConstants.INVOKE_SET_SUPPLIERID + i,
                        PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i));
                    StaticLog.debug("getMaterialPackageDataObjList---add");
                }
            }
            StaticLog.debug("supplierNums.size()---: " + supplierNums.size());
            if (0 < supplierNums.size()) {
                returnLists.add(packObj);
            }
        });
        StaticLog.debug("getMaterialPackageDataObjList----returnLists.size:" + returnLists.size());
        StaticLog.debug("getMaterialPackageDataObjList----returnLists:" + returnLists);
        return returnLists;
    }

    /**
     * 获取材料最新计划Object
     *
     * @return
     */
    public List<Object> getMaterialPackageDataObjListForLock(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        List<Object> packLists = Lists.newArrayList();
        if (getLastVer(projectId, 1)) {
            package100Service.listByMap(searchMap).stream().forEach(pack100 -> {
                String srmSyncStatus = PmsToolUtil.getStrValue(pack100, ApiConstants.INVOKE_GET_SRMSYNCSTATUS);
                if (!ApiConstants.PACKAGE_CONTRACT_ON.equals(srmSyncStatus)) {
                    packLists.add(pack100);
                }
            });
        } else {
            package200Service.listByMap(searchMap).stream().forEach(pack200 -> {
                String srmSyncStatus = PmsToolUtil.getStrValue(pack200, ApiConstants.INVOKE_GET_SRMSYNCSTATUS);
                if (!ApiConstants.PACKAGE_CONTRACT_ON.equals(srmSyncStatus)) {
                    packLists.add(pack200);
                }
            });
        }
        List<Object> returnLists = Lists.newArrayList();
        packLists.stream().forEach(packObj -> {
            List<String> supplierNums = Lists.newArrayList();
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                String supplierNum = PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);
                if (StrUtil.isNotEmpty(supplierNum)) {
                    supplierNums.add(supplierNum);
                }
            }
            if (0 < supplierNums.size()) {
                returnLists.add(packObj);
            }

        });
        returnLists.stream().forEach(reObj -> {
            StaticLog.info("reObj:  " + PmsToolUtil.getStrValue(reObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID));
            StaticLog.info("reObj:  " + PmsToolUtil.getStrValue(reObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID));
            StaticLog.info("reObj:  " + PmsToolUtil.getStrValue(reObj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID));
        });

        return returnLists;
    }

    /**
     * 获取当前项目大版本
     *
     * @param projectId 项目ID
     * @param kind      0 材料 1 分包
     * @return true 100  false 200
     */
    public Boolean getLastVer(Long projectId, Integer kind) {
        Boolean rs = Boolean.FALSE;
        BusProject busProject = this.getProjectInfo(projectId);
        BusVersion versionObj = null;
        if (0 == kind) {
            versionObj = busVersionService.getById(busProject.getVersionId());
        } else {
            versionObj = busVersionService.getById(busProject.getVersionpackageId());
        }
        if (null != versionObj && ApiConstants.VER_200 > Integer.valueOf(versionObj.getBigVersion())) {//返回100版本
            rs = Boolean.TRUE;
        }
        return rs;
    }

    /**
     * 通用计算结果获取
     *
     * @param calNm 数据字典分类名称
     * @param valNm 数据字典-子表-字典名称
     * @param vals  参数值
     * @return 计算结果
     */
    public BigDecimal getCalVal(String calNm, String valNm, BigDecimal... vals) {
        try {
            SysDict sysDict = dictService.findByType(calNm);
            Map<String, Object> dataSourceMap = Maps.newHashMap();
            List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
            SysDictData sysDictData = sysDictDatas.stream().filter(fil -> fil.getDicDataTitle().equals(valNm)).findFirst().get();
            for (int i = 0; i < vals.length; i++) {
                dataSourceMap.put("p" + i, vals[i]);
            }
            MyGroovyScriptEngine groovyScriptEngine = new MyGroovyScriptEngine();
            BigDecimal rs = groovyScriptEngine.executeBigDecimal(sysDictData.getDicDataValue(), dataSourceMap);
            if (null == rs) {
                return BigDecimal.ZERO;
            }
            return rs;

        } catch (Exception ex) {
            ex.printStackTrace();
            return BigDecimal.ZERO;
        }
    }

    public Boolean srmConnectionCheck() {
        try {
            SysDict sysDict = dictService.findByType("SRMCON");
            List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
            if (sysDictDatas.stream().anyMatch(fil -> fil.getDicDataTitle().equals("srmflg"))) {
                SysDictData sysDictData = sysDictDatas.stream().filter(fil -> fil.getDicDataTitle().equals("srmflg")).findFirst().get();
                if ("ON".equals(sysDictData.getDicDataValue())) {
                    StaticLog.debug("SRM接口通信接口开启。");
                    return Boolean.FALSE;
                }
            }
            StaticLog.debug("SRM接口通信接口关闭。");
            return Boolean.TRUE;

        } catch (Exception ex) {
            ex.printStackTrace();
            StaticLog.debug("SRM接口通信接口关闭。");
            return Boolean.TRUE;

        }
    }

    public Boolean oaConnectionCheck() {
        try {
            SysDict sysDict = dictService.findByType("OACON");
            List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
            if (sysDictDatas.stream().anyMatch(fil -> fil.getDicDataTitle().equals("oaflg"))) {
                SysDictData sysDictData = sysDictDatas.stream().filter(fil -> fil.getDicDataTitle().equals("oaflg")).findFirst().get();
                if ("ON".equals(sysDictData.getDicDataValue())) {
                    StaticLog.debug("OA接口通信接口开启。");
                    return Boolean.FALSE;
                }
            }
            StaticLog.debug("OA接口通信接口关闭。");
            return Boolean.TRUE;

        } catch (Exception ex) {
            ex.printStackTrace();
            StaticLog.debug("OA接口通信接口关闭。");
            return Boolean.TRUE;

        }
    }

    public SysDictData getSysDictData(String dictKey, String dicCode, String dicVal) {
        SysDict sysDict = dictService.findByType(dictKey);
        List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
        if (sysDictDatas.stream().anyMatch(dicObj -> dicObj.getDicDataTitle().equals(dicVal))) {
            return sysDictDatas.stream().filter(filterObj -> filterObj.getDicDataTitle().equals(dicVal)).findFirst().get();
        }
        return new SysDictData();

    }

    public Boolean sapConnectionForRecCheck() {
        try {
            SysDict sysDict = dictService.findByType("SAPREC");
            List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
            if (sysDictDatas.stream().anyMatch(fil -> fil.getDicDataTitle().equals("recflg"))) {
                SysDictData sysDictData = sysDictDatas.stream().filter(fil -> fil.getDicDataTitle().equals("recflg")).findFirst().get();
                if ("ON".equals(sysDictData.getDicDataValue())) {
                    StaticLog.debug("SAP接口通信接口打开。");
                    return Boolean.FALSE;
                }
            }
            StaticLog.debug("SAP接口通信接口关闭。");
            return Boolean.TRUE;

        } catch (Exception ex) {
            ex.printStackTrace();
            StaticLog.debug("SAP接口通信接口关闭。");
            return Boolean.TRUE;

        }
    }

    public List<SysDictData> getLgortsFromDic() {
        SysDict sysDict = dictService.findByType("lgort");
        List<SysDictData> sysDictDatas = dictDataService.findByDictId(sysDict.getDictId());
        return sysDictDatas;
    }

    // ------------------层级组装----------------------------start

    /**
     * 层级组装
     *
     * @param rsb
     */
    public static void levelProcess(ResultBody rsb) {
        Page page = (Page) rsb.getData();
        List<EntityMap> busMaterials = (List<EntityMap>) page.getRecords();
        if (0 == busMaterials.size()) {
            return;
        }

        Map<String, List<EntityMap>> outMapPlan = Maps.newHashMap();
        Map<String, List<EntityMap>> outMapPk = Maps.newHashMap();
        List<String> levelNos = Lists.newArrayList();
        busMaterials.stream().forEach(inObj -> {
            String materialCode = inObj.get("materialCode");
            String serviceCode = inObj.get("serviceCode");

            String levelNo = inObj.get("levelNo");
            List<EntityMap> updS = Lists.newArrayList();

            if (levelNo.endsWith(ApiConstants.DOUBLE_ZERO)) {
                levelNos.add(levelNo);
                updS.add(inObj);
            } else {
                if (StrUtil.isNotEmpty(materialCode)) {
                    if (outMapPlan.containsKey(levelNo.substring(0, 9) + ApiConstants.DOUBLE_ZERO)) {
                        updS = outMapPlan.get(levelNo.substring(0, 9) + ApiConstants.DOUBLE_ZERO);
                        updS.add(inObj);
                    }
                }
                if (StrUtil.isNotEmpty(serviceCode)) {
                    if (outMapPk.containsKey(levelNo.substring(0, 9) + ApiConstants.DOUBLE_ZERO)) {
                        updS = outMapPk.get(levelNo.substring(0, 9) + ApiConstants.DOUBLE_ZERO);
                        updS.add(inObj);
                    }
                }

            }
            if (StrUtil.isNotEmpty(materialCode)) {
                outMapPlan.put(levelNo, updS);
            } else {
                outMapPk.put(levelNo, updS);
            }
        });
        List<String> distinctLevels = levelNos.stream().distinct().collect(Collectors.toList());
        List<EntityMap> busMaterialsOut = Lists.newArrayList();
        distinctLevels.stream().forEach(level -> {
//            List<EntityMap> busMaterialsParent = Lists.newArrayList();
//            List<EntityMap> busMaterialsChild = Lists.newArrayList();
//
//            List<EntityMap> updSPlan = outMapPlan.get(level);
//            updSPlan.stream().forEach(outObj->{
//                String levelNo = outObj.get("levelNo");
//                if(levelNo.endsWith(ApiConstants.DOUBLE_ZERO)) {
//                    busMaterialsParent.add(outObj);
//                } else {
//                    busMaterialsChild.add(outObj);
//                }
//            });
//
//            busMaterialsParent.get(0).put("children", busMaterialsChild);
//            busMaterialsOut.addAll(busMaterialsParent);
//
//            List<EntityMap> updSPk = outMapPk.get(level);
            if (0 < outMapPlan.size() && null != outMapPlan.get(level)) {
                mkOutList(busMaterialsOut, outMapPlan.get(level), 0);
            }
            if (0 < outMapPk.size() && null != outMapPk.get(level)) {
                mkOutList(busMaterialsOut, outMapPk.get(level), 1);
            }
        });

        page.setRecords(busMaterialsOut);

        // return bizService.pageList(params);
        rsb.data(page);
    }

    private static void mkOutList(List<EntityMap> busMaterialsOut, List<EntityMap> updS, Integer kind) {
        List<EntityMap> busMaterialsParent = Lists.newArrayList();
        List<EntityMap> busMaterialsChild = Lists.newArrayList();
        updS.stream().forEach(outObj -> {
            String levelNo = outObj.get("levelNo");
            String materialCode = outObj.get("materialCode");
            if ((0 == kind && StrUtil.isNotEmpty(materialCode))
                ||
                (1 == kind && StrUtil.isEmpty(materialCode))) {
                if (levelNo.endsWith(ApiConstants.DOUBLE_ZERO)) {
                    busMaterialsParent.add(outObj);
                } else {
                    busMaterialsChild.add(outObj);
                }
            }
        });

        if (0 < busMaterialsParent.size()) {
            busMaterialsParent.get(0).put("children", busMaterialsChild);
            busMaterialsOut.addAll(busMaterialsParent);
        }

    }
    // ------------------层级组装----------------------------end

    /**
     * 更新工程量清单中的预算成本相关数据
     *
     * @param busMaterialParent 母表
     * @param costQuantity      100/200预算成本工程量
     */
    public static void updateBudget(BusMaterial busMaterialParent, BigDecimal costQuantity) {
        // 预算成本合价_未税_合价_主材费	【预算成本单价（未税）-单价-主材价】*【100/200预算成本工程量】
        busMaterialParent.setMainAmount(NumberUtil.mul(busMaterialParent.getMainPrice(), costQuantity));
        // 预算成本合价_未税_合价_安装费	【预算成本单价（未税）-单价-安装费】*【100/200预算成本工程量】
        busMaterialParent.setInstallAmount(NumberUtil.mul(busMaterialParent.getInstallPrice(), costQuantity));
        // 预算成本合价_未税_合价_合计	主材价+安装价
        busMaterialParent.setSyntheticalAmount(NumberUtil.add(busMaterialParent.getMainAmount(), busMaterialParent.getInstallAmount()));

        // 预估总产值_有合同价_合价_主材价	【对外合同单价-有合同价（单价）-主材价】*【100/200预算成本工程量】
        busMaterialParent.setMainsumPrice1(NumberUtil.mul(busMaterialParent.getMainPrice1(), costQuantity));
        // 预估总产值_有合同价_合价_安装价	【对外合同单价-有合同价（单价）-安装价】*【100/200预算成本工程量】
        busMaterialParent.setInstallsumPrice1(NumberUtil.mul(busMaterialParent.getInstallPrice1(), costQuantity));
        // 预估总产值_有合同价_合价_合计	主材价+安装价
        busMaterialParent.setContractsumSyntheticalPrice1(NumberUtil.add(busMaterialParent.getMainsumPrice1(), busMaterialParent.getInstallsumPrice1()));

        // 预估总产值_拟合同价_合价_主材价	【对外合同单价-拟合同价（单价）-主材价】*【100/200预算成本工程量】
        busMaterialParent.setMainsumPrice2(NumberUtil.mul(busMaterialParent.getMainPrice2(), costQuantity));
        // 预估总产值_拟合同价_合价_安装价	【对外合同单价-拟合同价（单价）-安装价】*【100/200预算成本工程量】
        busMaterialParent.setInstallsumPrice2(NumberUtil.mul(busMaterialParent.getInstallPrice2(), costQuantity));
        // 预估总产值_拟合同价_合价_合计	主材价+安装价
        busMaterialParent.setContractsumSyntheticalPrice2(NumberUtil.add(busMaterialParent.getMainsumPrice2(), busMaterialParent.getInstallsumPrice2()));

        // 预估总产值_合同价_合价_主材价	【对外合同单价-合同价（单价）-主材价】*【100/200预算成本工程量】
        busMaterialParent.setMainsumPrice3(NumberUtil.mul(busMaterialParent.getMainPrice3(), costQuantity));
        // 预估总产值_合同价_合价_安装价	【对外合同单价-合同价（单价）-安装价】*【100/200预算成本工程量】
        busMaterialParent.setInstallsumPrice3(NumberUtil.mul(busMaterialParent.getInstallPrice3(), costQuantity));
        // 预估总产值_合同价_合价_合计	主材价+安装价
        busMaterialParent.setContractsumSyntheticalPrice3(NumberUtil.add(busMaterialParent.getMainsumPrice3(), busMaterialParent.getInstallsumPrice3()));
    }

    /**
     * 更新最新版本各个计划数据
     *
     * @param subUpds 更新list
     * @param kind    0 材料 1 分包
     * @param ver     100 200 版本
     */
    public void updatePlanPackageData(List<Object> subUpds, int kind, int ver) {
        if (ApiConstants.INT_ZERO == kind) {
            // 材料
            if (ApiConstants.VER_100 == ver) {
                List<BusMaterialPlan100> upd100 = Lists.newArrayList();
                subUpds.stream().forEach(subOb -> {
                    upd100.add((BusMaterialPlan100) subOb);
                });
                if (0 < upd100.size()) {
                    plan100Service.updateBatchById(upd100);
                }

            } else {
                List<BusMaterialPlan200> upd200 = Lists.newArrayList();
                subUpds.stream().forEach(subObj -> {
                    upd200.add((BusMaterialPlan200) subObj);
                });
                if (0 < upd200.size()) {
                    plan200Service.updateBatchById(upd200);
                }
            }

        } else {
            if (ApiConstants.VER_100 == ver) {
                List<BusMaterialPackage100> upd100 = Lists.newArrayList();
                subUpds.stream().forEach(subObj -> {
                    upd100.add((BusMaterialPackage100) subObj);
                });
                if (0 < upd100.size()) {
                    package100Service.updateBatchById(upd100);
                }
            } else {
                List<BusMaterialPackage200> upd200 = Lists.newArrayList();
                subUpds.stream().forEach(subObj -> {
                    upd200.add((BusMaterialPackage200) subObj);
                });
                if (0 < upd200.size()) {
                    package200Service.updateBatchById(upd200);
                }
            }
        }
    }

    /**
     * 根据采购申请id， 子表ID获取SRM关联表数据
     *
     * @param purchaseId
     * @param purchaseDetailsId
     * @return
     */
    public BusMaterialSrm getBusMaterialSrm(Long purchaseId, Long purchaseDetailsId) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PURCHASEID, purchaseId);
        searchMap.put(ApiConstants.MAP_PURCHASEDETAILSID, purchaseDetailsId);
        return busMaterialSrmService.listByMap(searchMap).stream().findFirst().get();
    }

    /**
     * 根据采购申请id， 子表ID获取SRM关联表数据
     *
     * @param purchaseId
     * @param purchaseDetailsId
     * @return
     */
    public BusMaterialSrmSub getBusMaterialSrmSub(Long purchaseId, Long purchaseDetailsId) {
        Map<String, Object> searchMap = Maps.newHashMap();
        if (null != purchaseId && !purchaseId.equals(0L)) {
            searchMap.put(ApiConstants.MAP_PURCHASEID, purchaseId);
        }
        searchMap.put(ApiConstants.MAP_PURCHASEDETAILSID, purchaseDetailsId);
        return busMaterialSrmSubService.listByMap(searchMap).stream().findFirst().get();
    }

    /**
     * 获取分包合同关联表
     *
     * @param projectId 项目ID
     * @param majorCode 专业编码
     * @param packageNo 工程包
     * @return
     */
    public BusProjectPackSyncSrm getBusProjectPackSyncSrm(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        Collection<BusProjectPackSyncSrm> busProjectPackSyncSrms = packSyncSrmService.listByMap(searchMap);
        if (0 == busProjectPackSyncSrms.size()) {
            return null;
        }
        return busProjectPackSyncSrms.stream().findFirst().get();
    }

    public void updateBusProjectPackSyncSrm(BusProjectPackSyncSrm upd) {
        packSyncSrmService.updateById(upd);
    }

    public List<BusMaterialPackage100> getPackage100List(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        Collection<BusMaterialPackage100> package100s = package100Service.listByMap(searchMap);
        if (0 == package100s.size()) {
            return Lists.newArrayList();
        }
        return (List<BusMaterialPackage100>) package100s;
    }

    public List<BusMaterialPackage200> getPackage200List(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        Collection<BusMaterialPackage200> package200s = package200Service.listByMap(searchMap);
        if (0 == package200s.size()) {
            return Lists.newArrayList();
        }
        return (List<BusMaterialPackage200>) package200s;
    }

    public BusProjectSupplier getBusProjectSupplier(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        Collection<BusProjectSupplier> busProjectSuppliers = projectSupplierService.listByMap(searchMap);
        if (0 == busProjectSuppliers.size()) {
            return new BusProjectSupplier();
        }
        return busProjectSuppliers.stream().findFirst().get();
    }

    /**
     * 根据项目ID， 专业，工程包， 获取已绑定供应商列表
     *
     * @param projectId
     * @param majorCode
     * @param packageNo
     * @return
     */
    public List<BusSupplier> getBusProjectSuppliersForDelivery(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        Collection<BusProjectSupplier> busProjectSuppliers = projectSupplierService.listByMap(searchMap);
        List<BusSupplier> busSupplierOutList = Lists.newArrayList();
        if (0 < busProjectSuppliers.size()) {
            BusProjectSupplier busProjectSupplier = busProjectSuppliers.stream().findFirst().get();
            for (int i = 1; i < 11; i++) {
                Long supplierId = PmsToolUtil.getLongValue(busProjectSupplier, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (null != supplierId && 0L != supplierId) {
                    busSupplierOutList.add(supplierService.getById(supplierId));
                }
            }
        }
        return busSupplierOutList;
    }

    public BusSupplier getBusSupplier(Long supplierId, String supplierNo) {
        StaticLog.debug("getBusSupplier-supplierId:" + supplierId);
        StaticLog.debug("getBusSupplier-supplierNo:" + supplierNo);
        if (StrUtil.isNotEmpty(supplierNo)) {
            return supplierService.getByProperty(ApiConstants.MAP_SUPPLIERCODE, supplierNo);
        }
        return supplierService.getById(supplierId);
    }

    public BusSupplier getBusSupplier(String supplierName) {
        StaticLog.debug("supplierName:" + supplierName);
        return supplierService.getByProperty(ApiConstants.MAP_SUPPLIERNAME, supplierName);
    }

    public BusMaterialSrmSub getBusMaterialSrmSubForPackage(Long materialId, Long supplierId, Integer ver, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PACKAGECODE, packageNo);
        searchMap.put(ApiConstants.MAP_SUPPLIERID, supplierId);
        searchMap.put(ApiConstants.MAP_MATERIALPACKAGEID, materialId);
        StaticLog.info("packageNo:" + packageNo);
        StaticLog.info("supplierId:" + supplierId);
        StaticLog.info("materialId:" + materialId);
        StaticLog.info("ver:" + ver);
        if (ApiConstants.VER_100 == ver) {
            StaticLog.info("100");
            return busMaterialSrmSubService.listByMap(searchMap).stream().findFirst().get();

        } else {
            StaticLog.info("200");
            Collection<BusMaterialSrmSub> srmSubDataExists = busMaterialSrmSubService.listByMap(searchMap);
            if (0 == srmSubDataExists.size()) {
                Long pack100Id = package200Service.getById(materialId).getPackagePlan100Id();
                if (null != pack100Id) {
                    searchMap.put(ApiConstants.MAP_MATERIALPACKAGEID, pack100Id);
                    srmSubDataExists = busMaterialSrmSubService.listByMap(searchMap);
                    if (0 < srmSubDataExists.size()) {
                        return srmSubDataExists.stream().findFirst().get();
                    }
                }
            } else {
                return srmSubDataExists.stream().findFirst().get();
            }
        }
        return null;
    }

    public BusMaterialSrmSub getBusMaterialSrmSubForPackageForPms04(Long materialId, Long supplierId, Integer ver, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_MATERIALPACKAGEID, materialId);
        searchMap.put(ApiConstants.MAP_PACKAGECODE, packageNo);
        searchMap.put(ApiConstants.MAP_SUPPLIERID, supplierId);
        if (ApiConstants.VER_100 == ver) {
            return busMaterialSrmSubService.listByMap(searchMap).stream().findFirst().get();

        } else {
            Collection<BusMaterialSrmSub> srmSubDataExists = busMaterialSrmSubService.listByMap(searchMap);
            if (0 == srmSubDataExists.size()) {
                Long pack100Id = package200Service.getById(materialId).getPackagePlan100Id();
                if (null != pack100Id) {
                    searchMap.put(ApiConstants.MAP_MATERIALPACKAGEID, pack100Id);
                    return busMaterialSrmSubService.listByMap(searchMap).stream().findFirst().get();
                }
            }
        }

        return busMaterialSrmSubService.listByMap(searchMap).stream().findFirst().get();
    }

    public Collection<BusMaterialSrm> getBusMaterialSrmForPackage(Long projectId, String majorCode, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_MAJORCODE, majorCode);
        searchMap.put(ApiConstants.MAP_PACKAGECODE, packageNo);
        searchMap.put(ApiConstants.MAP_PLANDTLID, 0L);
        Collection<BusMaterialSrm> rs = busMaterialSrmService.listByMap(searchMap);
        if (0 == rs.size()) {
            return null;
        }
        return rs;
    }

    public Collection<BusMaterialSrmSub> getBusMaterialSrmSubForPackageForSrm03(Long projectId, String majorCode, String packageNo, Integer ver) {
        Collection<BusMaterialSrm> busMaterialSrms = getBusMaterialSrmForPackage(projectId, majorCode, packageNo);
        if (null == busMaterialSrms) {
            return Lists.newArrayList();
        }
        List<BusMaterialSrmSub> busMaterialSrmSubs = Lists.newArrayList();
//        Collection<BusMaterialSrmSub> busMaterialSrmSubs = Collections.EMPTY_LIST;
        busMaterialSrms.stream().forEach(srmObj -> {
            Map<String, Object> searchMap = Maps.newHashMap();
            searchMap.put(ApiConstants.MAP_BUSMATERIALSRMID, srmObj.getBusMaterialSrmId());
            Collection<BusMaterialSrmSub> rs = busMaterialSrmSubService.listByMap(searchMap);
            if (0 < rs.size()) {
                rs.stream().forEach(rsObj -> {
                    busMaterialSrmSubs.add(rsObj);
                });
            }
//            if (0 < rs.size()) {
//                busMaterialSrmSubs.addAll(rs);
//            }
        });

        if (0 == busMaterialSrmSubs.size()) {
            return Lists.newArrayList();
        }
        return busMaterialSrmSubs;

    }

    /**
     * @param projectId
     * @return
     */
    public List<BusMaterialPackage> getBusMaterialPackage(Long projectId) {
        return busMaterialSrmService.getBusMaterialPackage(projectId);
    }

    public Object getPackagePalnData(Integer ver, Long materialPackageId) {
        if (ApiConstants.VER_100 == ver) {
            return package100Service.getById(materialPackageId);
        }
        return package200Service.getById(materialPackageId);
    }

    public Object getPackagePalnDataNover(Long materialPackageId) {
        Object planData = package100Service.getById(materialPackageId);
        if (null == planData) {
            planData = package200Service.getById(materialPackageId);
        }

        return planData;
    }

    /**
     * @param projectId
     * @return
     */
    public List<BusMaterialSrmSub> getBusMaterialSrmSubsByProjectId(Long projectId, String kind) {
        if (ApiConstants.FB_PLANDATA.equals(kind)) {
            return busMaterialSrmSubService.getBusMaterialSrmForFb(projectId);
        } else {
            return busMaterialSrmSubService.getBusMaterialSrmForWz(projectId);
        }
//        Map<String, Object> srmMap = Maps.newHashMap();
//        srmMap.put(ApiConstants.MAP_PROJECTID, projectId);
//        Collection<BusMaterialSrm> srmS = busMaterialSrmService.listByMap(srmMap);
//        List<BusMaterialSrmSub> srmSubsList = Lists.newArrayList();
//        if(0 < srmS.size()) {
//            srmS.stream().forEach(srmInfo -> {
//                if(ApiConstants.FB_PLANDATA.equals(kind) &&  null == srmInfo.getPurchaseId()) {
//                    Map<String, Object> srmSubMap = Maps.newHashMap();
//                    srmSubMap.put(ApiConstants.MAP_BUSMATERIALSRMID, srmInfo.getBusMaterialSrmId());
//                    Collection<BusMaterialSrmSub> srmSubCollection = busMaterialSrmSubService.listByMap(srmSubMap);
//                    if (0 != srmSubCollection.size()) {
//                        srmSubsList.addAll(srmSubCollection);
//                    }
//                } else if(ApiConstants.WZ_PLANDATA.equals(kind) &&  null != srmInfo.getPurchaseId()) {
//                    Map<String, Object> srmSubMap = Maps.newHashMap();
//                    srmSubMap.put(ApiConstants.MAP_BUSMATERIALSRMID, srmInfo.getBusMaterialSrmId());
//                    Collection<BusMaterialSrmSub> srmSubCollection = busMaterialSrmSubService.listByMap(srmSubMap);
//                    if (0 != srmSubCollection.size()) {
//                        srmSubsList.addAll(srmSubCollection);
//                    }
//                }
//            });
//        }
//        return srmSubsList;
    }

    public BigDecimal getSupplierNum() {
        BigDecimal supplierNum = BigDecimal.ZERO;

        return supplierNum;
    }

    /**
     * 根据SRM合同明细ID获取SRMSUB数据
     *
     * @param contractsmatdtlId 合同明细ID
     * @return SrmSub数据
     */
    public BusMaterialSrmSub getBusMaterialSrmSubsBySrmContractDetailId(Long contractsmatdtlId, Integer contractRowno) {
        List<BusMaterialSrmSub> srmSubsList = Lists.newArrayList();
        Map<String, Object> srmMap = Maps.newHashMap();
        srmMap.put(ApiConstants.MAP_CONTRACTSMATDTLID, contractsmatdtlId);
        srmMap.put(ApiConstants.MAP_CONTRACTROWNO, contractRowno);
        Collection<BusMaterialSrmSub> srmSubCollection = busMaterialSrmSubService.listByMap(srmMap);
        if (0 != srmSubCollection.size()) {
            srmSubsList.addAll(srmSubCollection);
        } else {
            return null;
        }
        return srmSubsList.get(0);
    }

    public BusMaterialSrm getBusMaterialSrmSubByPackageNo(Long projectId, String packageNo) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_PACKAGENO, packageNo);
        searchMap.put(ApiConstants.MAP_PLANID, 0L);
        Collection<BusMaterialSrm> busMaterialSrms = busMaterialSrmService.listByMap(searchMap);
        if (0 == busMaterialSrms.size()) {
            return null;
        }
        return busMaterialSrms.stream().findFirst().get();
    }

    /**
     * 获取分包数据的专业，工程包
     * kind 0 获取专业 1 获取工程包
     *
     * @return 分包数据的专业，工程包
     */
    public List<Object> getMaterialPackageMajorList(Long projectId, int kind, String majorCode) {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        List<Object> packLists = Lists.newArrayList();
        if (getLastVer(projectId, 1)) {
            package100Service.listByMap(searchMap).stream().forEach(pack100 -> {
                packLists.add(pack100);
            });
        } else {
            package200Service.listByMap(searchMap).stream().forEach(pack200 -> {
                packLists.add(pack200);
            });
        }


        Map<String, String> returnMap = Maps.newHashMap();
        packLists.stream().forEach(packObj -> {
            if (0 == kind) {
                returnMap.put(PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_MAJORCODE), PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_MAJORNAME));
            } else {
                if (majorCode.equals(PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_MAJORCODE))) {
                    returnMap.put(PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_PACKAGENO), PmsToolUtil.getStrValue(packObj, ApiConstants.INVOKE_GET_PACKAGENAME));
                }
            }
        });
        List<Object> returnList = Lists.newArrayList();
        if (0 < returnMap.size()) {
            returnMap.forEach((key, val) -> {
                Map<String, String> data = Maps.newHashMap();
                if (0 == kind) {
                    data.put("majorCode", key);
                    data.put("majorName", val);
                } else {
                    data.put("packageCode", key);
                    data.put("packageName", val);
                }

                returnList.add(data);
            });
        }
        return returnList;
    }

    /**
     * 母表报表
     *
     * @param packagePlanId
     * @return
     */
    public Object get100PlanPackObj(Long packagePlanId, String type) {
        if (type.contains("材料")) {
            BusMaterialPlan200 busMaterialPlan200 = plan200Service.getById(packagePlanId);
            if (null != busMaterialPlan200) {
                return plan100Service.getById(busMaterialPlan200.getPackagePlan100Id());
            }
        } else if (type.contains("分包")) {
            BusMaterialPackage200 busMaterialPackage200 = package200Service.getById(packagePlanId);
            return package100Service.getById(busMaterialPackage200.getPackagePlan100Id());
        }

        return null;
    }

    public Long getRelationId(Object paobj, Integer ver) {
        if(ApiConstants.VER_100 == ver) {
            return PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID);
        }
        return PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_PackagePlan100Id);
    }

    /**
     * 获取有变更合同量的供应商
     *
     * @param packageData           父级节点数据
     * @param busMaterialSrmSubList SRM相关数据
     * @return
     */
    public List<Long> getChangedPackageDataOfSupplier(List<Object> packageData, Collection<BusMaterialSrmSub> busMaterialSrmSubList, Integer ver) {
        List<Long> vendors = Lists.newArrayList();

        List<Long> supperLists = getSupplierBySrmsubList(busMaterialSrmSubList);
        StaticLog.info("getChangedPackageDataOfSupplier---supperLists : " + supperLists);
        StaticLog.info("getChangedPackageDataOfSupplier---busMaterialSrmSubList : " + JSONArray.toJSONString(busMaterialSrmSubList));

        Map<Long, List<Object>> supplierMap = Maps.newHashMap();
        packageData.stream().forEach(paobj -> {
            for (int i = 1; i < ApiConstants.INT_ELEVEN; i++) {
                Long supplierId = PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_SUPPLIERID + i);
                if (null != supplierId && 0L != supplierId) {
                    if (supperLists.contains(supplierId)) {
                        //packagePlan100Id
                        Long compareId = getRelationId(paobj, ver);
//                        Long packagePlan100Id = PmsToolUtil.getLongValue(paobj, "getPackagePlan100Id");
//                        StaticLog.info("getChangedPackageDataOfSupplier---- packagePlan100Id: " + packagePlan100Id);
//                        Long materialPackage100Id = PmsToolUtil.getLongValue(paobj, ApiConstants.INVOKE_GET_MATERIALPACKAGE100ID);
                        BigDecimal supplierNum = PmsToolUtil.getBigDecimalValue(paobj, ApiConstants.INVOKE_GET_SUPPLIERNUM + i);
                        StaticLog.info("getChangedPackageDataOfSupplier--supplierId:" + supplierId);
                        StaticLog.info("getChangedPackageDataOfSupplier--compareId:" + compareId);
                        StaticLog.info("getChangedPackageDataOfSupplier--supplierNum:" + supplierNum);

                        if (BigDecimal.ZERO.compareTo(supplierNum) >= 0) {
                            StaticLog.info("getChangedPackageDataOfSupplier----该行计划该供应商，合同量已被冲销合计为0，请手动关闭SRM相关信息");
                        } else {
                            Collection<BusMaterialSrmSub> filterSrmSubList = busMaterialSrmSubList.stream().filter(srmSub ->
                                srmSub.getMaterialPackageId().equals(compareId)
                                    && srmSub.getSupplierId().equals(supplierId)
                            ).collect(Collectors.toList());

                            if (0 < filterSrmSubList.size()) {
                                StaticLog.info("getChangedPackageDataOfSupplier----该行计划该供应商已经下达过合同");
                                BusMaterialSrmSub srmSubFilter = filterSrmSubList.stream().findFirst().get();
                                if (supplierNum.compareTo(srmSubFilter.getPmsCount()) != 0) {
                                    StaticLog.info("getChangedPackageDataOfSupplier----该行计划该供应商已经下达过合同，发生变更数量");
                                    StaticLog.info("getChangedPackageDataOfSupplier----supplierNum：" + supplierNum);
                                    StaticLog.info("getChangedPackageDataOfSupplier----pmsCount：" + srmSubFilter.getPmsCount());
                                    if (!vendors.contains(supplierId)) {
                                        vendors.add(supplierId);
                                    }
                                } else {
                                    StaticLog.info("getChangedPackageDataOfSupplier----该行计划该供应商已经下达过合同，未发生变更数量");
                                }
                            } else {
                                if (!vendors.contains(supplierId)) {
                                    vendors.add(supplierId);
                                }
                                StaticLog.info("getChangedPackageDataOfSupplier----该行计划该供应商未下达过合同");
                            }
                        }
                    }
                }
            }
        });

        StaticLog.info("getChangedPackageDataOfSupplier----vendors:" + vendors);
        List<Long> vendorsOut = Lists.newArrayList();
        if (0 < vendors.size()) {
            vendors.stream().forEach(vendorId -> {
                if (supperLists.contains(vendorId)) {
                    vendorsOut.add(vendorId);
                } else {
                    StaticLog.info("getChangedPackageDataOfSupplier---该供应商未下达过合同vendorId：" + vendorId);
                }
            });
        }
        StaticLog.info("getChangedPackageDataOfSupplier----vendorsOut:" + vendorsOut);
        return vendorsOut;
    }

    /**
     * 获取SRM关联表中的供应商List
     *
     * @param busMaterialSrmSubList
     * @return
     */
    public List<Long> getSupplierBySrmsubList(Collection<BusMaterialSrmSub> busMaterialSrmSubList) {
        List<Long> supplierListBefores = Lists.newArrayList();
        busMaterialSrmSubList.stream().forEach(srmObj -> supplierListBefores.add(srmObj.getSupplierId()));
        return supplierListBefores.stream().distinct().collect(Collectors.toList());
    }

    public void setMapForImpCk(Map<String, List<Integer>> dataMap, Integer rowNum, String val) {
        if (StrUtil.isNotEmpty(val) && !"null".equals(val)) {
            if (dataMap.containsKey(val)) {
                dataMap.get(val).add(rowNum);
            } else {
                List<Integer> rowNumList = Lists.newArrayList();
                rowNumList.add(rowNum);
                dataMap.put(val, rowNumList);
            }
        }

    }

    /**
     * 母表模拟导入校验
     *
     * @param excelList
     * @return
     */
    public ResultBody impTestCkResult(List<Map<Object, Object>> excelList, Long projectId) throws ExecutionException, InterruptedException {
        StaticLog.info("impTestCkResult---start");
        // 存在性检查【非空，系统不存在】
        // 专业包代码
        // 工程包代码
        // 材料WBS代码
        // 全物料代码
        // 服务WBS代码
        // 服务代码
        // 层级号
        // 100预算成本工程量
        // 计量单位

        // 合理性校验
        // 层级号

        // WBS 行号
        Map<String, List<Integer>> majorMap = Maps.newHashMap();
        Map<String, List<Integer>> packageMap = Maps.newHashMap();
        Map<String, List<Integer>> wzWbsMap = Maps.newHashMap();
        Map<String, List<Integer>> materialMap = Maps.newHashMap();

        Map<String, List<Integer>> fbWbsMap = Maps.newHashMap();
        Map<String, List<Integer>> fbCodeMap = Maps.newHashMap();
        Map<String, List<Integer>> levelMap = Maps.newHashMap();
        Map<String, List<Integer>> costQuantity100Map = Maps.newHashMap();

        Map<String, List<Integer>> unitNameMap = Maps.newHashMap();

        // JSONArray excelArray = JSONUtil.parseArray(params.get("params"));
        excelList.stream().forEach(excelObj -> {
//            JSONObject jsonObject = (JSONObject)excelObj;
            String majorCode = String.valueOf(excelObj.get("专业包代码"));
            String packageCode = String.valueOf(excelObj.get("工程包代码"));
            String wzWbsCode = String.valueOf(excelObj.get("材料WBS代码"));
            String materialCode = String.valueOf(excelObj.get("全物料代码"));
            String fbWbsCode = String.valueOf(excelObj.get("服务WBS代码"));
            String fbWbs = String.valueOf(excelObj.get("服务代码"));
            String level = String.valueOf(excelObj.get("层级号"));
            String costQuantity100 = String.valueOf(excelObj.get("100预算成本工程量"));
            String unitName = String.valueOf(excelObj.get("计量单位"));

            // 行号
            Integer rowNum = excelList.indexOf(excelObj);

            setMapForImpCk(majorMap, rowNum, majorCode);
            setMapForImpCk(packageMap, rowNum, packageCode);
            setMapForImpCk(wzWbsMap, rowNum, wzWbsCode);
            setMapForImpCk(materialMap, rowNum, materialCode);
            setMapForImpCk(fbWbsMap, rowNum, fbWbsCode);
            setMapForImpCk(fbCodeMap, rowNum, fbWbs);
            setMapForImpCk(levelMap, rowNum, level);
            setMapForImpCk(costQuantity100Map, rowNum, costQuantity100);
            setMapForImpCk(unitNameMap, rowNum, unitName);
        });

        List<String> majorCodeList = majorMap.keySet().stream().collect(Collectors.toList());
        List<String> packageCodeList = packageMap.keySet().stream().collect(Collectors.toList());
        List<String> wzWbsList = wzWbsMap.keySet().stream().collect(Collectors.toList());
        List<String> materialList = materialMap.keySet().stream().collect(Collectors.toList());
        List<String> fbWbsList = fbWbsMap.keySet().stream().collect(Collectors.toList());
        List<String> fbCodeList = fbCodeMap.keySet().stream().collect(Collectors.toList());
        List<String> levelList = levelMap.keySet().stream().collect(Collectors.toList());
        List<String> costQuantityList = costQuantity100Map.keySet().stream().collect(Collectors.toList());
        List<String> unitNameList = unitNameMap.keySet().stream().collect(Collectors.toList());

        // 材料WBS代码--存在校验
//        List<List<String>> wbsGroup = PmsToolUtil.fixedGrouping(wzWbsList, 300);
//        List<String> wbsCkReturn = Lists.newArrayList();
//        wbsGroup.stream().forEach(wbs->{
//            wbsCkReturn.addAll(materialNoSyncCk.ckSycnFutureForWbs(wbs));
//        });
//        List<String> wbsCkReturn = materialNoSyncCk.ckSycnFutureForWbs(wzWbsList);
//        CompletableFuture<List<String>> wbsCkReturnSync = materialNoSyncCk.ckSycnFutureForWbs(wzWbsList);
        BusProject busProject = busProjectService.getById(projectId);
        List<String> wbsCkReturn = Lists.newArrayList();
//        List<List<String>> wbsGroup = PmsToolUtil.fixedGrouping(wzWbsList, 300);
//        wbsGroup.stream().forEach(wbs -> {
        try {
            wbsCkReturn.addAll(materialNoSyncCk.ckSycnFutureForWbs(wzWbsList, busProject.getProjectCode()).get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
//        });
        // 服务WBS代码--存在校验
//        List<String> wbsFbCkReturn = materialNoSyncCk.ckSycnFutureForWbs(fbWbsList, busProject.getProjectCode());
        CompletableFuture<List<String>> wbsFbCkReturnSync = materialNoSyncCk.ckSycnFutureForWbs(fbWbsList, busProject.getProjectCode());
        // 全物料代码--存在校验
        List<List<String>> materialCodeGroup = PmsToolUtil.fixedGrouping(materialList, 2000);
        List<String> materialCkReturn = Lists.newArrayList();
        materialCodeGroup.stream().forEach(materialCodeS -> {
            try {
                materialCkReturn.addAll(materialNoSyncCk.ckSycnFutureForMaterial(materialCodeS).get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
//        List<String> materialCkReturn = materialNoSyncCk.ckSycnFutureForMaterial(materialList);
//        CompletableFuture<List<String>> materialCkReturnSync = materialNoSyncCk.ckSycnFutureForMaterial(materialList);

        // 服务代码--存在校验
        List<String> fbCodeCkReturn = materialNoSyncCk.ckSycnFutureForSrmServiceCode(fbCodeList);
        // 计量单位--存在校验
//        List<String> unitCkReturn = materialNoSyncCk.ckSycnFutureForUnit(unitNameList);

//        CompletableFuture.allOf(wbsCkReturnSync, wbsFbCkReturnSync, materialCkReturnSync).join();

        List<Map<String, Object>> errList = Lists.newArrayList();
        if (null != wbsCkReturn) {
            setErrList("材料WBS代码【{}】系统中不存在", wbsCkReturn, wzWbsMap, errList);
        }
        if (null != materialCkReturn) {
            setErrList("全物料代码【{}】系统中不存在", materialCkReturn, materialMap, errList);
        }
        if (null != wbsFbCkReturnSync.get()) {
            setErrList("服务WBS代码【{}】系统中不存在", wbsFbCkReturnSync.get(), fbWbsMap, errList);
        }
        if (null != fbCodeCkReturn) {
            setErrList("服务代码【{}】系统中不存在", fbCodeCkReturn, fbCodeMap, errList);
        }
//        if(null != unitCkReturn) {
//            setErrList("计量单位【{}】系统中不存在", unitCkReturn, unitNameMap, errList);
//        }
        StaticLog.info("impTestCkResult---end");
        return ResultBody.ok(errList);
    }

    private void setErrList(String msgFormat, List<String> notExistsList, Map<String, List<Integer>> rowNumMap, List<Map<String, Object>> errList) {
        notExistsList.stream().forEach(materialStr -> {
            List<Integer> rowNumLists = rowNumMap.get(materialStr);
            rowNumLists.stream().forEach(materialErrStr -> {
                errList.add(
                    setErrMap("第" + (materialErrStr + 2) + "行",
                        StrUtil.format(msgFormat, materialStr))
                );
            });
        });
    }

    private Map<String, Object> setErrMap(String errNo, String errMsg) {
        Map<String, Object> errMap = Maps.newHashMap();
        errMap.put("errNo", errNo);
        errMap.put("errMsg", errMsg);
        return errMap;
    }

    public SrmService getSrmService(String serviceCode) {
        return srmServiceService.getByProperty("serviceCode", serviceCode);
    }

    public ResultBody ckRerport(List<EntityMap> listentityMap) {
        String packageNo = listentityMap.get(0).get("packageNo");
        Long projectId = listentityMap.get(0).getLong("projectId");

        List<Long> supplierIds = Lists.newArrayList();
        Map<Long, List<Long>> dataMap = Maps.newHashMap();
        listentityMap.stream().forEach(reportMapObj -> {
            Long supplierId = reportMapObj.getLong("supplierId");
            Long materialId = reportMapObj.getLong("materialId");

            if (dataMap.containsKey(supplierId)) {
                dataMap.get(supplierId).add(materialId);
            } else {
                List<Long> reportIds = Lists.newArrayList();
                reportIds.add(materialId);
                dataMap.put(supplierId, reportIds);
                supplierIds.add(supplierId);
            }
        });

        CriteriaQuery<BusMaterialSrmSub> srmSubCriteriaQuery = new CriteriaQuery(BusMaterialSrmSub.class);
        srmSubCriteriaQuery.eq("projectId", projectId);
        srmSubCriteriaQuery.eq("packageCode", packageNo);
        srmSubCriteriaQuery.in("supplierId", supplierIds);
        srmSubCriteriaQuery.select(" DISTINCT supplierId");
        List<BusMaterialSrmSub> busMaterialSrmSubList = busMaterialSrmSubService.list(srmSubCriteriaQuery);
        if (0 == busMaterialSrmSubList.size()) {
            return ResultBody.failed("未签署合同!");
        }
        if (busMaterialSrmSubList.size() != supplierIds.size()) {
            return ResultBody.failed("存在未签署合同的供应商!");
        }
        return ResultBody.ok();
    }

    public void setPlanPackageDataToReqMap(Map map, Long projectId, String packageNo, String majorCode, Integer planType, String appKind) {
        List<Object> rs = Lists.newArrayList();
        if (ApiConstants.ENGINEER_APPROVAL_FB_100_UPD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_FB_100_ADD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_FB_200_UPD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_FB_200_ADD.equals(appKind)) {
            Map<String, Object> searchMap = Maps.newHashMap();
            searchMap.put("projectId", projectId);
            searchMap.put("packageNo", packageNo);
            searchMap.put("majorCode", majorCode);
            searchMap.put("planType", planType);
            searchMap.put("versionStatus", 0);
            //分包100
            if (ApiConstants.ENGINEER_APPROVAL_FB_100_UPD.equals(appKind)
                || ApiConstants.ENGINEER_APPROVAL_FB_100_ADD.equals(appKind)) {
                rs.addAll(package100Service.listByMap(searchMap));

            } else if (ApiConstants.ENGINEER_APPROVAL_FB_200_UPD.equals(appKind)
                || ApiConstants.ENGINEER_APPROVAL_FB_200_ADD.equals(appKind)) {
                //分包200
                rs.addAll(package200Service.listByMap(searchMap));
            }

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD.equals(appKind)
            || ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD.equals(appKind)) {

            List<String> majorCodes = busMajorService.getUserMajors(OpenHelper.getUserId());
            //材料100
            if (ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD.equals(appKind)
                || ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD.equals(appKind)) {
                CriteriaUpdate<BusMaterialPlan100> cu = new CriteriaUpdate<>();
                cu.eq("projectId", projectId);
                cu.eq("planType", planType);
                cu.eq("versionStatus", 0);
                if (majorCodes.size() > 0) {
                    if (!majorCodes.contains("P99")) {
                        cu.in("majorCode", majorCodes);
                    }
                }
                rs.addAll(plan100Service.list(cu));
            } else if (ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD.equals(appKind)
                || ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD.equals(appKind)) {
                //材料200
                CriteriaUpdate<BusMaterialPlan200> cu = new CriteriaUpdate<>();
                cu.eq("projectId", projectId);
                cu.eq("planType", planType);
                cu.eq("versionStatus", 0);
                if (majorCodes.size() > 0) {
                    if (!majorCodes.contains("P99")) {
                        cu.in("majorCode", majorCodes);
                    }
                }
                rs.addAll(plan200Service.list(cu));
            }
        }
        map.put(ApiConstants.OA_APPROVAL_DATA, rs);
        StaticLog.info("setPlanPackageDataToReqMap-----rs:" + rs);

    }

    // 搜索新增数据中，的追加数据当中，是否有审批中行-追加
    public ResultBody chkImpExcelContentForPlanData(List<Map<Object, Object>> excelContentList, String ckKind) {
        List<Integer> rowCkList = Lists.newArrayList();
        excelContentList.stream().forEach(excelContent -> {
            int rowNum = excelContentList.indexOf(excelContent);
            if (ApiConstants.WZ_PLANDATA.equals(ckKind)) {
                if (!PmsToolUtil.ckNullStr(String.valueOf(excelContent.get("是否新增")))
                    && String.valueOf(excelContent.get("是否新增")).equals("是")
                    && !PmsToolUtil.ckNullStr(String.valueOf(excelContent.get("材料id")))
                ) {
                    String planId = String.valueOf(excelContent.get("材料id"));
                    Boolean existsCk =
                        excelContentList.stream().anyMatch(excelCkObj ->
                            !PmsToolUtil.ckNullStr(String.valueOf(excelCkObj.get("审批状态")))
                                && String.valueOf(excelCkObj.get("审批状态")).equals("1")
                                && String.valueOf(excelCkObj.get("材料id")).equals(planId)
                        );
                    if (existsCk) {
                        rowCkList.add(rowNum);
                    }
                }
            } else {
                if (!PmsToolUtil.ckNullStr(String.valueOf(excelContent.get("是否新增")))
                    && String.valueOf(excelContent.get("是否新增")).equals("是")
                    && !PmsToolUtil.ckNullStr(String.valueOf(excelContent.get("分包Id")))
                ) {
                    String packageId = String.valueOf(excelContent.get("分包Id"));
                    Boolean existsCk =
                        excelContentList.stream().anyMatch(excelCkObj ->
                            !PmsToolUtil.ckNullStr(String.valueOf(excelCkObj.get("oa审批状态")))
                                && String.valueOf(excelCkObj.get("oa审批状态")).equals("1")
                                && String.valueOf(excelCkObj.get("分包Id")).equals(packageId)
                        );
                    if (existsCk) {
                        rowCkList.add(rowNum);
                    }
                }
            }

        });
        if (0 < rowCkList.size()) {
            StringBuffer str = new StringBuffer();
            rowCkList.stream().forEach(rowNum -> {
                str.append(rowNum + 3);
                str.append(",");
            });
            str.replace(str.length() - 1, str.length(), "");
            StaticLog.debug("第" + str.toString() + "行数据的上一层为审核中数据，无法进行审批。");
            return ResultBody.failed("第" + str.toString() + "行数据的上一层为审核中数据，无法进行审批。");
        }
        return ResultBody.ok();
    }

    public ResultBody ckSrmContractStatus(Long projectId, String packageNo) {
        Boolean rs = Boolean.FALSE;
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put("projectId", projectId);
        searchMap.put("packageNo", packageNo);
        Collection<BusProjectPackSyncSrm> busProjectPackSyncSrms = busProjectPackSyncSrmService.listByMap(searchMap);
        if (0 < busProjectPackSyncSrms.size()) {
            boolean can = true;
            for (BusProjectPackSyncSrm item : busProjectPackSyncSrms) {
                for (int i = 1; i <= 10; i++) {
                    String syncStatus = PmsToolUtil.getStrValue(item, ApiConstants.INVOKE_GET_SYNCSTATUS + i);
                    if (ApiConstants.PACKAGE_SRM_SYNC_ING.equals(syncStatus)) {
                        can = false;
                        break;
                    }
                    if (!can) {
                        break;
                    }
                }
            }
            if (can) {
                return ResultBody.ok(0);
            }
            return ResultBody.failed("工程包【" + packageNo + "】已下达合同，请在SRM系统中，完成该合同！");
        }
        return ResultBody.ok(0);
    }

    public Boolean ckPackageIdForSrmContract(Long projectId, String packageNo) {
        Boolean ck = Boolean.TRUE;
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_PROJECTID, projectId);
        searchMap.put(ApiConstants.MAP_PACKAGECODE, packageNo);
        Collection<BusMaterialSrmSub> srmSubs = busMaterialSrmSubService.listByMap(searchMap);
//        searchMap = Maps.newHashMap();
//        searchMap.put(ApiConstants.MAP_PROJECTCODE, projectCode);
//        Collection<BusProject> busProjects = busProjectService.listByMap(searchMap);
        if (0 < srmSubs.size()) {
            if (!getLastVer(projectId, 1)) {
                ck = Boolean.FALSE;
            }
        }
        return ck;
    }
}

